/*
 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cJSON.h>
#include "ohos_init.h"
#include "los_task.h"
#include "oc_mqtt.h"
#include "e53_smart_covers.h"
#include "lz_hardware.h"
#include "config_network.h"
#include <stdio.h>
#include <string.h>


#include <unistd.h>
#include <math.h>





#define ROUTE_SSID                      "Abcd"
#define ROUTE_PASSWORD                  "panyusen18747668165"

#define MSG_QUEUE_LENGTH                16
#define BUFFER_LEN                      50

//#define CLIENT_ID                       "6612bf472ccc1a5838802a8a_pys2206_0_1_2024040717"
//#define USERNAME                        "6612bf472ccc1a5838802a8a_pys2206"
//#define PASSWORD                        "4ed5a7fb9aa4d2d2a7813aa46a0ab9a641c56ca71ba3c12619253cf2e026e0d6"


#define CLIENT_ID                       "6612bf472ccc1a5838802a8a_pys2206_0_0_2024040718"
#define USERNAME                        "6612bf472ccc1a5838802a8a_pys2206"
#define PASSWORD                        "4ca2337e7c1294df681b6656a41c8c1f161c6707563998b60960e80631c82c49"

typedef struct
{
    void *x;
    int y;
    int z;
    unsigned int tilt_status;
} sc_report_t;

typedef struct
{
    en_msg_type_t msg_type;
    sc_report_t report;
} sc_msg_t;

static unsigned int m_sc_msg_queue;



////new uart////
/*
 * UART2_TX_M1 -> GPIO0_B3
 * UART2_RX_M1 -> GPIO0_B2
 */
#define UART_ID                 2

// 字符串最大长度
#define STRING_MAXSIZE          128

// FiFo最大单位数量
#define FIFO_MAX_UNIT           176
// FiFo结构体，用于存放串口接收
struct tagFifo {
    int max;            // 缓冲区最大单元数目
    int read;           // 读操作的偏移位置
    int write;          // 写操作的偏移位置
    unsigned char buffer[FIFO_MAX_UNIT];
};
// 定义串口接收的Fifo缓冲区
static struct tagFifo m_uart_recv_fifo = {
    .max = FIFO_MAX_UNIT,
    .read = 0,
    .write = 0,
};



// 判断Fifo是否已满
static int fifo_is_full(struct tagFifo *fifo)
{
    int write_next = (fifo->write + 1) % (fifo->max);
    if (write_next == fifo->read)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

// 专门负责串口接收的任务
void uart2_recv_process()
{

    unsigned int ret;
    UartAttribute attr;

   

    LzUartDeinit(UART_ID);
    
    attr.baudRate = 38400;
    attr.dataBits = UART_DATA_BIT_8;
    attr.pad = FLOW_CTRL_NONE;
    attr.parity = UART_PARITY_NONE;
    attr.rxBlock = UART_BLOCK_STATE_NONE_BLOCK;
    attr.stopBits = UART_STOP_BIT_1;
    attr.txBlock = UART_BLOCK_STATE_NONE_BLOCK;
    
    PinctrlSet(GPIO0_PB3, MUX_FUNC3, PULL_KEEP, DRIVE_LEVEL2);
    PinctrlSet(GPIO0_PB2, MUX_FUNC3, PULL_KEEP, DRIVE_LEVEL2);
    
    ret = LzUartInit(UART_ID, &attr);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
        return;
    }
    LOS_Msleep(1000);



    unsigned char recv_buffer[STRING_MAXSIZE];
    unsigned int recv_length = 0;

    while (1) 
    {
        recv_length = 0;
        memset(recv_buffer, 0, sizeof(recv_buffer));
        recv_length = LzUartRead(UART_ID, recv_buffer, sizeof(recv_buffer));
        if (recv_length > 0)
        {
            // printf("%s, %d: uart recv and str(%s), len(%d)\n", __FILE__, __LINE__, recv_buffer, recv_length);
            // 写入到FiFo
            for (int i = 0; i < recv_length; i++)
            {
                if (fifo_is_full(&m_uart_recv_fifo) != 0) 
                {
                    printf("%s, %d: uart recv str, fifo is full\n", __FILE__, __LINE__);
                    printf("\n");
                    printf("------start-----------\n");
                    int y=0;
                    for(;y<176;y++){
                     printf("%d\n",m_uart_recv_fifo.buffer[y]);
                    
                    }
                    printf("\n");
                    printf("------end-----------\n");
                    
                    ////////////send queue////////////////
                    
                     sc_msg_t *app_msg = NULL;
 
       
        printf("send queue!!!!!!!!!!!\n");
        
       
        app_msg = malloc(sizeof(sc_msg_t));
        if (app_msg != NULL)
        {
        
            app_msg->msg_type = en_msg_report;
            char str[700]="";
             char sp[4];
            
            
            int y=0;
            for(;y<176;y++){
            sprintf(sp, "%d", m_uart_recv_fifo.buffer[y]);
            strcat(str,sp);
            sprintf(sp, "%c", 97);
            strcat(str,sp);
            
                    }
        
            
            printf("%d\n",strlen(str));
            printf("%s\n",str);
            
            app_msg->report.x = str;
            app_msg->report.y = 1;
            app_msg->report.z = 1;
            app_msg->report.tilt_status = 1;
            if (LOS_QueueWrite(m_sc_msg_queue, (void *)app_msg, sizeof(sc_msg_t), LOS_WAIT_FOREVER) != LOS_OK)
            {
                printf("%s LOS_QueueWrite fail\n", __func__);
                free(app_msg);
            }
        }
        LOS_Msleep(2000);
              
                    ////////////////////////////
                    
                    
                    
                }
                m_uart_recv_fifo.buffer[m_uart_recv_fifo.write] = recv_buffer[i];
                m_uart_recv_fifo.write = (m_uart_recv_fifo.write + 1) % (m_uart_recv_fifo.max);
            }
        }
        LOS_Msleep(1);
    }
}




//////new uart/////
/* 定义ADC的通道号 */
#define ADC_CHANNEL         5
/* 定义ADC初始化的结构体 */
static DevIo m_adcKey = {
    .isr =   {.gpio = INVALID_GPIO},
    .rst =   {.gpio = INVALID_GPIO},
    .ctrl1 = {.gpio = GPIO0_PC5, .func = MUX_FUNC1, .type = PULL_NONE, .drv = DRIVE_KEEP, .dir = LZGPIO_DIR_IN, .val = LZGPIO_LEVEL_KEEP},
    .ctrl2 = {.gpio = INVALID_GPIO},
};


/***************************************************************
* 函数名称: adc_dev_init
* 说    明: 初始化ADC
* 参    数: 无
* 返 回 值: 0为成功，反之为失败
***************************************************************/
static unsigned int adc_dev_init()
{
    unsigned int ret = 0;
    uint32_t *pGrfSocCon29 = (uint32_t *)(0x41050000U + 0x274U);
    uint32_t ulValue;

    ret = DevIoInit(m_adcKey);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Key IO Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }
    ret = LzSaradcInit();
    if (ret != LZ_HARDWARE_SUCCESS) {
        printf("%s, %s, %d: ADC Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }

    /* 设置saradc的电压信号，选择AVDD */
    ulValue = *pGrfSocCon29;
    ulValue &= ~(0x1 << 4);
    ulValue |= ((0x1 << 4) << 16);
    *pGrfSocCon29 = ulValue;
    
    return 0;
}

/***************************************************************
* 函数名称: Get_Voltage
* 说    明: 获取ADC电压值
* 参    数: 无
* 返 回 值: 电压值
***************************************************************/
static float adc_get_voltage()
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    unsigned int data = 0;

    ret = LzSaradcReadValue(ADC_CHANNEL, &data);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return 0.0;
    }

    return (float)(data * 3.3 / 1024.0);
}

/***************************************************************
* 函数名称: adc_process
* 说    明: ADC采集循环任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/







/* E53模块中
 * UART0_RX_M0 -> GPIO0_B6
 * UART0_TX_M0 -> GPIO0_B7
 */
//#define UART_ID                 0

//#define STRING_MAXSIZE          128

void uart_process(void)
{
    unsigned int ret;
    UartAttribute attr;
    //unsigned char str[] = 0x8A;
    unsigned char str[]= {0x8A};
    unsigned char recv_buffer[STRING_MAXSIZE];
    unsigned int recv_length = 0;
    unsigned int i;
    
    /* 初始化adc设备 */
    adc_dev_init();

    LzUartDeinit(UART_ID);
    
    attr.baudRate = 38400;
    attr.dataBits = UART_DATA_BIT_8;
    attr.pad = FLOW_CTRL_NONE;
    attr.parity = UART_PARITY_NONE;
    attr.rxBlock = UART_BLOCK_STATE_NONE_BLOCK;
    attr.stopBits = UART_STOP_BIT_1;
    attr.txBlock = UART_BLOCK_STATE_NONE_BLOCK;
    
    PinctrlSet(GPIO0_PB3, MUX_FUNC3, PULL_KEEP, DRIVE_LEVEL2);
    PinctrlSet(GPIO0_PB2, MUX_FUNC3, PULL_KEEP, DRIVE_LEVEL2);
    
    ret = LzUartInit(UART_ID, &attr);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
        return;
    }
    LOS_Msleep(1000);
    int flag=0;

    while (1)
    {
    
    float vl=adc_get_voltage();
    
    
    
        printf("%s, %d: uart write and str(%s), len(%d)!\n", __FILE__, __LINE__, str, strlen(str));
        // LzUartWrite是异步发送，非阻塞发送
       // if(flag==0){
       
        //}
        
        if((0.11>=vl)&&(vl>=0.00)){
         printf("fasongE\n");
        LzUartWrite(UART_ID, str, 1);
        
        // 等待发送完毕
        LOS_Msleep(2000);


    printf("kkkkkk\n");
    }

        recv_length = 0;
        memset(recv_buffer, 0, sizeof(recv_buffer));
        recv_length = LzUartRead(UART_ID, recv_buffer, sizeof(recv_buffer));
        if(recv_length!=0){
        flag=1;
        }
        printf("%s, %d: uart recv and str(%s), len(%d)\n", __FILE__, __LINE__, recv_buffer, recv_length);
        
        printf("-----\n");
        int ij=0;
        for(;ij<128;ij++){
        printf("s:%d",recv_buffer[ij]);
        printf("LIU:%X",recv_buffer[ij]);
        }
        
        
        printf("-----\n");
        
        printf("");

        LOS_Msleep(2000);
    }
    
    return;
}














/***************************************************************
* 函数名称: sc_deal_report_msg
* 说    明: 上报智慧井盖模块数据到华为云上
* 参    数: report：智慧农业上报消息指针
* 返 回 值: 无
***************************************************************/
void sc_deal_report_msg(sc_report_t *report)
{
    oc_mqtt_profile_service_t service;
    oc_mqtt_profile_kv_t x;
 

    service.event_time = NULL;
    service.service_id = "heart";
    service.service_property = &x;
    service.nxt = NULL;

    x.key = "body";
    x.value = *(&report->x);
    x.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
   //  x.type = EN_OC_MQTT_PROFILE_VALUE_INT;
    x.nxt = NULL;



    oc_mqtt_profile_propertyreport(USERNAME, &service);
    return;
}

/***************************************************************
* 函数名称: iot_cloud_sc_thread
* 说    明: 华为云消息线程
* 参    数: 无
* 返 回 值: 无
***************************************************************/
int iot_cloud_sc_thread()
{
    uint8_t hwaddr[6]  = {0x10, 0xdc, 0xb6, 0x90, 0x00, 0x00};
    sc_msg_t *app_msg = NULL;
    unsigned int addr;
    int ret;

    FlashInit(); 
    VendorSet(VENDOR_ID_MAC,               hwaddr,         6);  // 多人同时做该实验，请修改各自不同的WiFi MAC地址
    VendorSet(VENDOR_ID_WIFI_ROUTE_SSID,   ROUTE_SSID,     sizeof(ROUTE_SSID));
    VendorSet(VENDOR_ID_WIFI_ROUTE_PASSWD, ROUTE_PASSWORD, sizeof(ROUTE_PASSWORD));
    SetWifiModeOn();

    device_info_init(CLIENT_ID, USERNAME, PASSWORD);
    ret = oc_mqtt_init();
    if (ret != LOS_OK)
    {
        printf("oc_mqtt_init fail ret:%d\n", ret);
    }

    while (1)
    {
        ret = LOS_QueueRead(m_sc_msg_queue, (void *)&addr, BUFFER_LEN, LOS_WAIT_FOREVER);
        if (ret == LOS_OK)
        {
            app_msg = addr;
            switch (app_msg->msg_type)
            {
                case en_msg_report:
                    sc_deal_report_msg(&app_msg->report);
                    printf("-------updata data----------------\n");
                    LOS_Msleep(5000);
                    break;
                default:
                    break;
            }
            free(app_msg);
            app_msg = NULL;
        }
        else
        {
            LOS_Msleep(100);
        }
    }
}

/***************************************************************
* 函数名称: e53_sc_thread
* 说    明: E53智慧井盖线程
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void e53_sc_thread()
{
    sc_msg_t *app_msg = NULL;
 

    while (1)
    {
       // e53_sc_read_data(&data);
        printf("x is  %d\n", 1);
        printf("y is  %d\n", 1);
        printf("z is  %d\n", 1);
        
       
        app_msg = malloc(sizeof(sc_msg_t));
        if (app_msg != NULL)
        {
            app_msg->msg_type = en_msg_report;
            
            int num = 123;
            char str[176]="";
            char sp[4];
            sprintf(sp, "%d", num);
            strcat(str,sp);
            sprintf(sp, "%c", 97);
            strcat(str,sp);
            
            sprintf(sp, "%d", num);
            strcat(str,sp);
            
            printf("%d\n",strlen(str));
            printf("%s\n",str);
            
            app_msg->report.x = str;
            app_msg->report.y = 1;
            app_msg->report.z = 1;
            app_msg->report.tilt_status = 1;
            if (LOS_QueueWrite(m_sc_msg_queue, (void *)app_msg, sizeof(sc_msg_t), LOS_WAIT_FOREVER) != LOS_OK)
            {
                printf("%s LOS_QueueWrite fail\n", __func__);
                free(app_msg);
            }
        }
        LOS_Msleep(2000);
    }
}

/***************************************************************
* 函数名称: iot_cloud_sc_example
* 说    明: 华为云智慧井盖例程
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void iot_cloud_sc_example()
{
    unsigned int ret = LOS_OK;
    unsigned int thread_id1;
    unsigned int thread_id2;
    unsigned int thread_id3;
    TSK_INIT_PARAM_S task1 = {0};
    TSK_INIT_PARAM_S task2 = {0};
    TSK_INIT_PARAM_S task3 = {0};

    ret = LOS_QueueCreate("queue", MSG_QUEUE_LENGTH, &m_sc_msg_queue, 0, BUFFER_LEN);
    if (ret != LOS_OK)
    {
        printf("Falied to create Message Queue ret:0x%x\n", ret);
        return;
    }

    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)iot_cloud_sc_thread;
    task1.uwStackSize = 10240;
    task1.pcName = "iot_cloud_sc_thread";
    task1.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id1, &task1);
    if (ret != LOS_OK)
    {
        printf("Falied to create iot_cloud_sc_thread ret:0x%x\n", ret);
        return;
    }

    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)uart2_recv_process;
    task2.uwStackSize = 2048;
    task2.pcName = "uart2 recv process";
    task2.usTaskPrio = 25;
    ret = LOS_TaskCreate(&thread_id2, &task2);
    if (ret != LOS_OK)
    {
        printf("Falied to create e53_sc_thread ret:0x%x\n", ret);
        return;
    }
    
    
    task3.pfnTaskEntry = (TSK_ENTRY_FUNC)uart_process;
    task3.uwStackSize = 2048;
    task3.pcName = "uart2 recv process";
    task3.usTaskPrio = 26;
    ret = LOS_TaskCreate(&thread_id3, &task3);
    if (ret != LOS_OK)
    {
        printf("Falied to create e53_sc_thread ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(iot_cloud_sc_example);
